<template>
  <vxe-pulldown ref="pullRef" placement="bottom-start" :style="{ width: width ? width + 'px' : '100%' }" transfer>
    <template #default>
      <div style="position: relative; display: flex">
        <ltext
          ref="jselectRef"
          :model-value="modelValue"
          :disabled="disabled"
          :clearable="clearable"
          :size="size"
          :height="height"
          :placeholder="placeholder"
          :autoSelect="autoSelect"
          style="width: 100%"
          @focus="focusEvent"
          @keydown.stop="keydownEvent"
          @clear="clear"
          @input="changeInput"
        />
        <lbtn title="弹出选择商品" v-if="showMore" size="mini" type="text" @click="clickMore">选</lbtn>
      </div>
    </template>
    <template #dropdown>
      <div class="pull-wrapper" ref="wrapperRef">
        <template v-if="state.list.length > 0">
          <div
            :id="'id' + item[valueKey]"
            :class="['list-item2', currentIndex === index ? 'active' : '']"
            v-for="(item, index) in state.list"
            :key="index"
            @mousedown.prevent="mouseDown($event, item)"
          >
            <div style="flex: 1; color: #1e9fff; font-weight: 600;font-size: 14px;">
              <span>{{ item.ext }}{{ item[labelKey] }}</span>
            </div>
            <div style="padding-left: 10px; color: #8a8f97">
              {{ item.suffix }}
            </div>
          </div>
        </template>
      </div>
      <div class="add-row" v-if="addItem" @mousedown="addItemClick">
        <lbtn size="mini" icon="plus" type="text">新增</lbtn>
      </div>
    </template>
  </vxe-pulldown>
</template>
<script>
import tool from '@/utils/tool';
export default {
	props: {
		width: { type: [String, Number], default: '' },
		modelValue: { type: [String, Number], default: '' },
		invId: { type: [String, Number], default: '' },
		buId: { type: [String, Number], default: '' },
		unit: { type: [String, Number], default: '' },
		transType: { type: [String, Number], default: '' },
		qty: { type: [String, Number], default: '' },
		sql: { type: String, default: '' },
		size: { type: String, default: 'small' },
		valueKey: { type: String, default: 'id' },
		labelKey: { type: String, default: 'name' },
		moreCat: { type: String, default: 'goods' },
		searchKey: { type: String, default: '' },
		height: { type: [String, Number], default: '' },
		showMore: { type: Boolean, default: false },
		loadOnce: { type: Boolean, default: false },
		addItem: { type: Boolean, default: false },
		disabled: { type: Boolean, default: false },
		autoSelect: { type: Boolean, default: false },
		clearable: { type: Boolean, default: true },
		isGrid: { type: Boolean, default: false }, // 下拉 表格
		list: { type: [String, Array], default: '' },
		focusOpen: { type: Boolean, default: true }, // focus自动打开
		readonly: { type: Boolean, default: false }, // 必填
		required: { type: Boolean, default: false }, // 必填
		pinYin: { type: Boolean, default: false }, // 拼音
		border: { type: Boolean, default: true }, // 禁用
		className: { type: String, default: '' }, // 自定义样式
		borderColor: { type: String, default: '' }, // 边框色
		bgColor: { type: String, default: '' }, // 背景色
		listWidth: { type: Number, default: 0 }, // 下拉框宽度
		cat: { type: String, default: '' }, // 取数据cat分类
		placeholder: { type: String, default: '' }, // 取数据cat分类
		options: {
			type: Array,
			default: () => {
				return [];
			},
		}, // 如果传入值
	},
	data() {
		return {
			show: false,
			showMorePanel: false,
			currentPage: 1,
			pageSize: 30,
			total: 0,
			state: {
				list: this.list,
			},
			currentIndex: -1,
		};
	},
	emits: ['update:modelValue', 'update:id', 'change', 'enter', 'Esc', 'down', 'up', 'left', 'right', 'itemAdd', 'clickMore'],
	watch: {
		list: {
			handler(val) {
				this.state.list = val;
			},
			deep: true,
		},
		modelValue(val) {
			if (!val) this.$emit('update:id', null);
		},
	},
	computed: {
		showMoreComputed() {
			return this.showMore && this.cat === 'invName';
		},
	},
	methods: {
    clickMore () {
      this.$emit('clickMore',this.buId)
      this.$refs.pullRef.hidePanel();
    },
		focusEvent() {
			if (this.focusOpen) {
				this.currentIndex = -1;
				if (!this.modelValue) this.changeInput(this.modelValue);
			}
		},
		blurEvent() {
			this.hidePanel();
		},
		isOpen() {
			return this.$refs.pullRef.isPanelVisible();
		},
		keydownEvent(e) {
			let key = e.key ? e.key : e.$event.key;
			let start = e.target.selectionStart; // 光标位置
			switch (key) {
				case 'Enter':
					{
						if (this.currentIndex > -1 && this.currentIndex < this.state.list.length) {
							this.setData(this.state.list[this.currentIndex]);
							this.currentIndex = -1;
              this.$emit('enter')
						}
						else if (this.currentIndex === -1) {
							if (this.state.list && this.state.list.length === 1) {
								this.setData(this.state.list[0]);
                this.$emit('enter');
							} else {
								if (this.modelValue && !this.invId) {
									if(this.showMore) {
                    this.$emit('clickMore',this.buId)
                  }
									this.$refs.pullRef.hidePanel();
								}
                else {
									this.$emit('enter');
								}
							}
						}
					}
					break;
				case 'ArrowLeft':
					{
						if (start === 0) {
							this.$emit('left');
						}
					}
					break;
				case 'ArrowRight':
					{
						if (start === (this.modelValue ? tool.xe.toString(this.modelValue).length : 0)) {
							this.$emit('right');
						}
					}
					break;
				case 'ArrowDown':
					{
						if (!e.ctrlKey) {
							if (this.isOpen()) {

								if (this.currentIndex < this.state.list.length - 1) {
									this.currentIndex++;
									this.scrollToOption(true, this.state.list[this.currentIndex]);
								} else {
									let optWrapperElem = this.$refs.wrapperRef;
									this.currentIndex = 0;
									optWrapperElem.scrollTo(0, 0);
								}
							} else {
								this.$emit('down');
							}
						}
					}
					break;
				case 'ArrowUp':
					{
						if (!e.ctrlKey) {
							if (this.isOpen()) {
								if (this.currentIndex > 0 && this.currentIndex <= this.state.list.length - 1) {
									this.currentIndex--;
								} else {
									this.currentIndex = this.state.list.length - 1;
								}
								this.scrollToOption(false, this.state.list[this.currentIndex]);
							} else {
								this.$emit('up');
							}
						}
					}
					break;
				case 'Escape':
					{
						this.hidePanel();
						this.$emit('Esc');
					}
					break;
			}
		},
		clear() {
			this.$emit('update:modelValue', null);
			this.$emit('update:id', null);
			this.$emit('change', null);
			this.currentIndex = -1;
			this.hidePanel();
		},
		changeInput(value) {
			if (this.disabled) return;
			this.$emit('update:modelValue', value);
			if (this.loadOnce) {
				if (this.state.list.length > 0) {
					return;
				}
			}
			let searchTxt = value ? tool.xe.trim(value) : '';
			if (this.list.length > 0) {
				if (searchTxt) {
					this.state.list = this.list.filter((row) => {
						return row[this.labelKey].indexOf(searchTxt) !== -1;
					});
				}
				this.openPanel();
			} else if (this.sql) {
				let sql = this.sql;
				if (searchTxt) {
					if (this.pinYin) {
						sql += ` and (${this.labelKey} like '%${searchTxt}%' or pinYin like '%${searchTxt}%') `;
					} else {
						sql += ` and ${this.labelKey} like '%${searchTxt}%' `;
					}
				}
				tool.post('common/doSql', { sql: sql }).then((ret) => {
					if (ret.data && ret.data.length > 0) {
						this.state.list = ret.data;
						this.openPanel();
					}
				});
			} else if (this.cat) {
				this.state.list = [];
				tool
					.post('common/dropdown', {
						cat: this.cat,
						keyWord: searchTxt,
						invId: this.invId,
						buId: this.buId,
						unit: this.unit,
						transType: this.transType,
						qty: this.qty,
					})
					.then((ret) => {
						if (ret.stat) {
							if (ret.data && ret.data.length > 0) {
								this.state.list = ret.data;
								this.openPanel();
							}
						}
					});
			}
		},
		openPanel() {
			if (this.$refs.pullRef) this.$refs.pullRef.showPanel();
		},
		hidePanel() {
			if (this.$refs.pullRef) this.$refs.pullRef.hidePanel();
		},
		mouseDown(e, item) {
			e.preventDefault();
			this.setData(item);
			this.currentIndex = -1;
			setTimeout(() => {
				this.$emit('enter');
			}, 0);
		},
		scrollToOption(isAlignBottom, item) {
			let optWrapperElem = this.$refs.wrapperRef;
			let panelElem = this.$refs.wrapperRef;
			let optElem = panelElem.querySelector('#id' + item.id);
			if (optWrapperElem && optElem) {
				let wrapperHeight = panelElem.offsetHeight;
				let offsetPadding = 5;
				if (isAlignBottom) {
					if (optElem.offsetTop + optElem.offsetHeight - panelElem.scrollTop > wrapperHeight) {
						optWrapperElem.scrollTo(0, optElem.offsetTop + optElem.offsetHeight - wrapperHeight);
					}
				} else {
					optWrapperElem.scrollTo(0, optElem.offsetTop - offsetPadding);
				}
			}
		},
		setData(item) {
			let id = item[this.valueKey];
			let text = item[this.labelKey];
			this.$emit('update:modelValue', text);
			this.$emit('update:id', id);
			this.$emit('change', item);
			this.hidePanel();
		},
		down(e) {
			e.preventDefault();
		},
		addItemClick() {
			this.$emit('itemAdd');
			this.$refs.pullRef.hidePanel();
		},
	},
};
</script>

<style scoped lang="scss">
.list-item2 {
	//height: 30px;
	//line-height: 30px;
	padding: 5px;
	white-space: nowrap;
	display: flex;
	&.active {
		background-color: #dcdfe6;
	}
	&:hover {
		background-color: #dcdfe6;
		cursor: pointer;
	}
}
.el-input-group__append {
	padding: 0 2px !important;
}
.more {
	&:hover {
		cursor: pointer;
	}
}
.pull-wrapper {
	height: 300px;
	overflow: auto;
	//box-shadow: 0 2px 5px 0 #E5E5E5;
	box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);
	width: auto;
}
.add-row {
	height: 40px;
	line-height: 40px;
	text-align: center;
	color: #8a8f97;
	background-color: var(--el-bg-color-page);
	border-left: var(--el-border);
	border-right: var(--el-border);
	border-bottom: var(--el-border);
	&:hover {
		cursor: pointer;
		color: #1e9fff;
	}
}
</style>